package com.tiamo.chatgpt.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tiamo.chatgpt.common.constants.RedisCacheKeys;
import com.tiamo.chatgpt.common.constants.RedisCacheNames;
import com.tiamo.chatgpt.common.enums.ChatKeyStatusEnum;
import com.tiamo.chatgpt.domain.chatKey.ChatKeyDto;
import com.tiamo.chatgpt.entity.ChatKeyEntity;
import com.tiamo.chatgpt.mapper.ChatKeyMapper;
import com.tiamo.chatgpt.service.ChatKeyService;
import com.tiamo.chatgpt.util.RedisUtil;
import com.tiamo.common.web.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import java.util.Objects;

/**
 * api-key
 *
 * @author luozhiwei
 * @date 2023/6/5 下午11:40
 */
@Service
@Slf4j
public class ChatKeyServiceImpl extends ServiceImpl<ChatKeyMapper, ChatKeyEntity> implements ChatKeyService {

    @Resource
    private RedisUtil redisUtil;


    /**
     * 查询可用
     *
     * @return
     */
    @Override
    public List<ChatKeyDto> listByUsable() {
        List<ChatKeyDto> chatKeyDtos = redisUtil.listGetAllAndConvert(RedisCacheNames.BASE + RedisCacheKeys.CHAT_KEY, ChatKeyDto.class);
        if (CollUtil.isEmpty(chatKeyDtos)) {
            List<ChatKeyEntity> list = lambdaQuery().eq(ChatKeyEntity::getStatus, ChatKeyStatusEnum.YES.getCode())
                    .orderByDesc(ChatKeyEntity::getUpTime).list();
            chatKeyDtos = Convert.toList(ChatKeyDto.class, list);
            if (CollUtil.isEmpty(chatKeyDtos)) {
                throw new BizException("无可用api-key配置，请联系管理员");
            }
            redisUtil.listSetAll(RedisCacheNames.BASE + RedisCacheKeys.CHAT_KEY, chatKeyDtos);
        }
        return chatKeyDtos;
    }

    /**
     * 修改
     *
     * @param dto
     * @return
     */
    @Override
    public Boolean edit(ChatKeyDto dto) {
        if (Objects.isNull(dto) || Objects.isNull(dto.getId())) {
            throw new BizException("请求参数异常");
        }
        boolean update = lambdaUpdate().eq(ChatKeyEntity::getId, dto.getId())
                .set(StringUtils.isNotBlank(dto.getApiKey()), ChatKeyEntity::getApiKey, dto.getApiKey())
                .set(StringUtils.isNotBlank(dto.getDescription()), ChatKeyEntity::getDescription, dto.getDescription())
                .set(Objects.nonNull(dto.getStatus()), ChatKeyEntity::getStatus, dto.getStatus())
                .update();
        if (update) {
            redisUtil.del(RedisCacheNames.BASE + RedisCacheKeys.CHAT_KEY);
        }
        return update;
    }

    /**
     * 修改
     *
     * @param dto
     * @return
     */
    @Override
    public Boolean add(@Valid ChatKeyDto dto) {
        if (Objects.isNull(dto)) {
            throw new BizException("请求参数异常");
        }
        ChatKeyEntity entity = ChatKeyEntity.builder()
                .apiKey(dto.getApiKey())
                .description(dto.getDescription())
                .status(Objects.isNull(dto.getStatus()) ? ChatKeyStatusEnum.YES.getCode() : dto.getStatus())
                .build();
        boolean save = save(entity);
        if (save) {
            redisUtil.del(RedisCacheNames.BASE + RedisCacheKeys.CHAT_KEY);
        }
        return save;
    }

    /**
     * 获取下一个可用编号
     *
     * @return
     */
    @Override
    public String next() {
        List<ChatKeyDto> chatKeyDtos = listByUsable();
        if (CollUtil.isEmpty(chatKeyDtos)) {
            throw new BizException("无可用KEY,请联系管理员");
        }
        Object apiKey = redisUtil.get(RedisCacheNames.CHAT_KEY + RedisCacheKeys.LAST_ONE_KEY);
        if (Objects.isNull(apiKey)) {
            return listByUsable().get(0).getApiKey();
        }

        boolean flag = false;
        for (ChatKeyDto chatKeyDto : chatKeyDtos) {
            if (chatKeyDto.getApiKey().equals(apiKey)) {
                flag = true;
            }
            if (flag) {
                return chatKeyDto.getApiKey();
            }
        }

        return listByUsable().get(0).getApiKey();
    }

    /**
     * 获取用户当前缓存的key
     *
     * @param userId
     * @return
     */
    @Override
    public String getUserCache(String userId) {
        if (StringUtils.isBlank(userId)) {
            log.error("getByUserCache userId is null");
            throw new BizException("系统异常,未获取到用户账号。请联系管理员");
        }
        String s = redisUtil.get(RedisCacheNames.CHAT_KEY + RedisCacheKeys.USER_CURRENT_KEY + userId).toString();
        if (StringUtils.isBlank(s)) {
            return next();
        }
        return s;
    }

    /**
     * 设置用户当前缓存的key
     *
     * @param userId
     * @return
     */
    @Override
    public void setUserCache(String userId, String apiKey) {
        if (StringUtils.isBlank(userId)) {
            log.error("setUserCache userId is null");
            throw new BizException("系统异常,未获取到用户账号。请联系管理员");
        }
        redisUtil.set(RedisCacheNames.CHAT_KEY + RedisCacheKeys.USER_CURRENT_KEY + userId, apiKey);
    }

    /**
     * 通过参数查询分页数据
     *
     * @param page
     * @param size
     * @param status
     * @return
     */
    @Override
    public Page<ChatKeyDto> pageByParam(Integer page, Integer size, Integer status) {

        Page<ChatKeyDto> resultPage = (Page<ChatKeyDto>) lambdaQuery().eq(Objects.nonNull(status), ChatKeyEntity::getStatus, status)
                .orderByDesc(ChatKeyEntity::getUpTime)
                .page(new Page<ChatKeyEntity>(page, size)).convert(a -> {
                    return Convert.convert(ChatKeyDto.class, a);
                });

        return resultPage;
    }
}
